package com.njym.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.njym.annotation.PermInfo;
import com.njym.entity.*;
import com.njym.payment.alipay.service.AliPayService;
import com.njym.payment.wxpay.service.WxService;
import com.njym.service.*;
import com.njym.tradeStatusConfig.WxTradeStatus;
import com.njym.vo.Json;
import com.njym.vo.ReconciliationsVo;
import com.njym.vo.RequestDate;
import com.njym.webservice.WebService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @program: ReconciliationsController
 * @description:
 * @author: yh
 * @create: 2018-09-12 13:57
 **/
@PermInfo(value = "对账记录接口")
@RestController
@RequestMapping("/Reconciliations")
public class ReconciliationsController {

    @Autowired
    private ReconciliationsService reconciliationsService;

    @Autowired
    private SysOrganizationService sysOrganizationService;

    @Autowired
    private SysPaymentModeService sysPaymentModeService;

    @Autowired
    private AliPayService aliPayService;

    @Autowired
    private WxService wxService;

    @Autowired
    private WebService webService;

    @Autowired
    private PlatformBusinessRecService platformBusinessRecService;

    @Autowired
    private OrgBusinessRecService orgBusinessRecService;
    private static final Logger log = LoggerFactory.getLogger(ReconciliationsController.class);

    @RequestMapping("/getAppData")
    public Json getAppData(RequestDate requestDate){
        String oper = "list appData result";
        log.info("{}, body: {}", oper, requestDate);

        String startDate = requestDate.getStartDate();
        String endDate = requestDate.getEndDate();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = null;
        Date end = null;
        try {
            start = sdf.parse(startDate);
            end = sdf.parse(endDate);
        }
        catch (ParseException e) {
            e.printStackTrace();
        }
        String orgId = "1109347597304803330";
        ReconciliationsVo list = reconciliationsService.getAppResult(start,end,"",orgId);
        ReconciliationsVo jiaoyi = reconciliationsService.getAppResult(start,end,"1",orgId);
        ReconciliationsVo tuikuan = reconciliationsService.getAppResult(start,end,"2",orgId);
        EntityWrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
        queryParams.isNotNull("trade_no");
        queryParams.eq("org_id", orgId);
        queryParams.between("create_date",start,end);
        List<PlatformBusinessRec> platformBusinessRecslist = platformBusinessRecService.selectList(queryParams);
        if(jiaoyi==null){
            jiaoyi = new ReconciliationsVo();
            jiaoyi.setTotalCount(0);
            jiaoyi.setTotalFee(new BigDecimal(0));
        }
        if(tuikuan==null){
            tuikuan = new ReconciliationsVo();
            tuikuan.setTotalCount(0);
            tuikuan.setTotalFee(new BigDecimal(0));
        }
        return Json.succ(oper, "total", list ).data("jiaoyi",jiaoyi).data("tuikuan",tuikuan).data("detail",platformBusinessRecslist);
    }

    @PostMapping("/listorg")
    public Json listOrg(@RequestBody String body) {
        String oper = "list org result";
        log.info("{}, body: {}", oper, body);

        JSONObject json = JSON.parseObject(body);
        Subject currentUser = SecurityUtils.getSubject();
        SysUser user = (SysUser)currentUser.getPrincipal();
        String orgId = user.getOrgId();
        if (orgId.equals("0")) {
            orgId = null;
        }

        String source = json.getString("source");
        BigDecimal totalFee = json.getBigDecimal("totalFee");
        Integer totalCount = json.getInteger("totalCount");

        Object timeInterval = json.get("timeInterval");
        Date start = null;
        Date end = null;
        if (timeInterval != null && timeInterval.getClass() == JSONArray.class) {
            JSONArray timeIntervalarr = (JSONArray)timeInterval;
            start = timeIntervalarr.getTimestamp(0);
            end = timeIntervalarr.getTimestamp(1);
        }
        System.out.println(start);
        System.out.println(end);
        List<ReconciliationsVo> list = reconciliationsService.getOrgResult(orgId,source,totalFee,totalCount,start,end);
        System.out.print(list);
        return Json.succ(oper, "list", list );
    }

    /**
     * 手动执行对账并查询记录
     * @param body
     * @return
     */
    @PostMapping("/manuallistorg")
    public Json manuallistorg(@RequestBody String body) {
        String oper = "list org result";
        log.info("{}, body: {}", oper, body);

        JSONObject json = JSON.parseObject(body);
        Subject currentUser = SecurityUtils.getSubject();
        SysUser user = (SysUser)currentUser.getPrincipal();
        String orgId = user.getOrgId();
        if ("0".equals(orgId)) {
            orgId = null;
        }

        String source = json.getString("source");
        BigDecimal totalFee = json.getBigDecimal("totalFee");
        Integer totalCount = json.getInteger("totalCount");

        Object timeInterval = json.get("value2");
        String time = timeInterval+"";
        String time1=time+" 00:00:00";
        String time2 = time+" 23:59:59";
        Date start = null;
        Date end = null;
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
             start = fmt.parse(time1);
              end  = fmt.parse(time2);
        }catch (ParseException e){
            e.printStackTrace();
        }

        List<ReconciliationsVo> list = reconciliationsService.getOrgResult(orgId,source,totalFee,totalCount,start,end);
        return Json.succ(oper, "list", list );
    }

    @PostMapping("/synchronize")
    public Json queryTime(@RequestBody String body){
        JSONObject json = JSON.parseObject(body);
        Object timeInterval = json.get("value2");
        String billDate = timeInterval+"";
        String time1=billDate+" 00:00:00";
        String time2 = billDate+" 23:59:59";
        EntityWrapper<OrgBusinessRec> queryParams = new EntityWrapper<>();
        queryParams.between("create_date",time1,time2);
        List<OrgBusinessRec> list = orgBusinessRecService.selectList(queryParams);
        boolean flag = true;
        if (list.size()>0){
            flag=false;
        }else{
             new Thread(()->this.reconciliations(billDate)).start();
        }
        return Json.result("flag",flag);
    }


    public void reconciliations(String billDate) {
        Wrapper<SysOrganization> queryParams = new EntityWrapper<>();
        queryParams.orderBy("sort_no", true);
        queryParams.eq("deleted", 0);
        List<SysOrganization> sysOrganizationList = sysOrganizationService.selectList(queryParams);
        List<Object> list = new ArrayList<>();
        if (sysOrganizationList != null && sysOrganizationList.size() > 0) {
            for (SysOrganization sysOrganization : sysOrganizationList) {
                String dataUrl = sysOrganization.getDataUrl();
                if(StringUtils.isNotBlank(dataUrl) && !list.contains(dataUrl)){
                    list.add(dataUrl);
                    // TODO 获取机构的dataUrl从his取数据到中间表
                     String getDataResult = webService.getData(dataUrl, billDate, billDate);
                         if (!WxTradeStatus.SUCCESS.equals(getDataResult)) {
                            continue;
                          }
                }
                String orgId = sysOrganization.getId();
                Wrapper<SysPaymentMode> payModeParams = new EntityWrapper<>();
                payModeParams.orderBy("sort_no", true);
                payModeParams.eq("org_id", orgId);
                payModeParams.eq("deleted", 0);
                List<SysPaymentMode> sysPaymentModes = sysPaymentModeService.selectList(payModeParams);
                if (sysPaymentModes != null && sysPaymentModes.size() > 0) {
                    for (SysPaymentMode sysPaymentMode : sysPaymentModes) {
                        String modeId = sysPaymentMode.getId();
                        switch (sysPaymentMode.getModeCode()) {
                            case "alipay":
                                //支付宝对账
                                JSONObject jsonObject = aliPayService.aliPayBill(orgId, billDate);
                                String result = jsonObject.getString("result");
                                if (WxTradeStatus.SUCCESS.equals(result)) {
                                    String path = jsonObject.getString("path");
                                    //平台与支付宝对账
                                    aliPayService.reconciliationAliPayBill(orgId, modeId, path, billDate);
                                }
                                break;
                            case "wxpay":
                                wxService.downloadWxPayBill(orgId, modeId, billDate);
                            default:
                                break;
                        }
                        //平台与机构对账
                        this.reconciliationPlatformOrgBill(orgId, modeId, billDate);
                    }
                }
            }
        }
    }

    private void reconciliationPlatformOrgBill(String orgId, String modeId, String billDate) {
        OrgBusinessRec orgBusinessRec = new OrgBusinessRec();
        Wrapper<OrgBusinessRec> orgParam = new EntityWrapper<>();
        orgParam.eq("org_id", orgId);
        orgParam.eq("mode_id", modeId);
        orgParam.between("billing_date", billDate + " 00:00:00", billDate + " 23:59:59");
        List<OrgBusinessRec> orgBusinessRecList = orgBusinessRec.selectList(orgParam);
        Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
        queryParams.isNotNull("trade_no");
        queryParams.eq("org_id", orgId);
        queryParams.eq("mode_id", modeId);
        queryParams.between("trade_date", billDate + " 00:00:00", billDate + " 23:59:59");
        List<PlatformBusinessRec> platformBusinessRecList = platformBusinessRecService.selectList(queryParams);
        for (PlatformBusinessRec platformBusinessRec : platformBusinessRecList) {
            String outTradeNo = platformBusinessRec.getOutTradeNo();
            boolean existFlag = false;
            for (OrgBusinessRec orgRec : orgBusinessRecList) {
                if (orgRec.getOutTradeNo().equals(outTradeNo)) {
                    existFlag = true;
                    orgRec.setAccountFlag(Byte.valueOf("1"));
                    orgRec.updateById();
                }
            }
            Date nowDate = new Date();
            platformBusinessRec.setAccountFlag(Byte.valueOf("1"));
            platformBusinessRec.setAccountDate(nowDate);
            if (existFlag) {
                platformBusinessRec.setAbnormalFlag(Byte.valueOf("0"));
            } else {
                //异常记录 长款
                platformBusinessRec.setAbnormalFlag(Byte.valueOf("1"));
                ReconcileAbnormalRec reconcileAbnormalRec = new ReconcileAbnormalRec();
                reconcileAbnormalRec.setOrgId(platformBusinessRec.getOrgId());
                reconcileAbnormalRec.setChannelId(platformBusinessRec.getChannelId());
                reconcileAbnormalRec.setModeId(platformBusinessRec.getModeId());
                reconcileAbnormalRec.setRecType(platformBusinessRec.getRecType());
                reconcileAbnormalRec.setTradeNo(platformBusinessRec.getTradeNo());
                reconcileAbnormalRec.setOutTradeNo(platformBusinessRec.getOutTradeNo());
                reconcileAbnormalRec.setPlatformFee(platformBusinessRec.getTotalFee());
                reconcileAbnormalRec.setOrgFee(new BigDecimal(0).setScale(2, BigDecimal.ROUND_HALF_UP));
                reconcileAbnormalRec.setStatus(Byte.valueOf("1"));
                reconcileAbnormalRec.setCreateDate(platformBusinessRec.getCreateDate());
                reconcileAbnormalRec.insert();
            }
            platformBusinessRec.updateById();
        }
        for (OrgBusinessRec orgRec : orgBusinessRecList) {
            String orgOutTradeNo = orgRec.getOutTradeNo();
            boolean existFlag = false;
            if (orgRec.getAccountFlag() == 1) {
                break;
            }
            for (PlatformBusinessRec platformBusinessRec : platformBusinessRecList) {
                if (platformBusinessRec.getAccountFlag() == 1) {
                    break;
                }
                if (platformBusinessRec.getOutTradeNo().equals(orgOutTradeNo)) {
                    existFlag = true;
                    platformBusinessRec.setAccountFlag(Byte.valueOf("1"));
                    platformBusinessRec.setAccountDate(new Date());
                    platformBusinessRec.setAbnormalFlag(Byte.valueOf("0"));
                    platformBusinessRec.updateById();
                }
            }
            if (existFlag) {
                orgRec.setAccountFlag(Byte.valueOf("1"));
                orgRec.updateById();
            } else {
                ReconcileAbnormalRec reconcileAbnormalRec = new ReconcileAbnormalRec();
                reconcileAbnormalRec.setOrgId(orgRec.getOrgId());
                reconcileAbnormalRec.setChannelId(orgRec.getChannelId());
                reconcileAbnormalRec.setModeId(orgRec.getModeId());
                reconcileAbnormalRec.setTradeNo(orgRec.getTradeNo());
                reconcileAbnormalRec.setOutTradeNo(orgRec.getOutTradeNo());
                reconcileAbnormalRec.setPlatformFee(new BigDecimal(0).setScale(2, BigDecimal.ROUND_HALF_UP));
                reconcileAbnormalRec.setOrgFee(orgRec.getTotalFee());
                reconcileAbnormalRec.setStatus(Byte.valueOf("1"));
                reconcileAbnormalRec.setCreateDate(orgRec.getCreateDate());
                reconcileAbnormalRec.insert();
            }
            orgRec.setAccountFlag(Byte.valueOf("1"));
            orgRec.updateById();
        }
    }
}
